package com.lanmao.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.lanmao.blog.vo.BlogTags;
import com.lanmao.blog.entity.Blog;
import com.lanmao.blog.entity.Count;
import com.lanmao.blog.entity.Tag;
import com.lanmao.blog.entity.Tags;
import com.lanmao.blog.mapper.BlogMapper;
import com.lanmao.blog.mapper.TagMapper;
import com.lanmao.blog.mapper.TagsMapper;
import com.lanmao.blog.service.BlogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lanmao.blog.vo.CountVo;
import com.lanmao.blog.vo.FristBlog;
import com.lanmao.blog.vo.HotBlog;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lanmao
 * @since 2022-03-13
 */
@Transactional(rollbackFor=Exception.class)  //开启事务
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {

    @Autowired
    BlogMapper blogMapper;
    @Autowired
    TagMapper tagMapper;
    @Autowired
    TagsMapper tagsMapper;
    @Autowired
    StringRedisTemplate redisTemplate;

    /**
     * 后台系统博客查询
     * @param current
     * @param limit
     * @param published
     * @param flag
     * @param share_statement
     * @param is_delete
     * @return
     */
    @Override
    public Page<Blog> pageBlogs(Long current, Long limit, Boolean published, String flag,
                       Boolean share_statement, Boolean is_delete) {
        //创建Page对象
        Page<Blog> blogPage = new Page<Blog>(current,limit);
        //构建条件
        QueryWrapper<Blog> wrapper = new QueryWrapper<Blog>();
        if (published != null) wrapper.eq("published",published);
        if (flag != null) wrapper.eq("flag",flag);
        if (share_statement != null) wrapper.eq("share_statement",share_statement);
        if (is_delete != null)  wrapper.eq("is_delete",is_delete);
        wrapper.orderByDesc("update_time");
        blogMapper.selectPage(blogPage,wrapper);
        return blogPage;
    }
    @Override
    public List<Blog> getByTitle(String title) {
        List<Blog> list = blogMapper.getByTitle(title);
        return list;

    }

    /**
     * 前台首页博客数据
     * @param current
     * @param size
     * @param type_id
     * @param tags_id
     * @return
     */
    //@Cacheable(value = "prefindByPage",key = "'prefindByPage'")
    @Override
    public HashMap<String, Object> prefindByPage(Long current, Long size, Long type_id, Long tags_id) {
        current = current ==null? 0 : current;
        size = size==null? 4 : size;
        HashMap<String,Object> map = new HashMap<>();
        //分页查询出当前页面显示的数据
        List<FristBlog> blogList = blogMapper.prefindByPage((current-1) * size,size,type_id,tags_id);
        //查询数据的总条数
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        int size1 = blogList.size();
        wrapper.eq("published",1).eq("share_statement",1);
        if (type_id!=null){
            wrapper.eq("type_id", type_id);
        }
        Integer count = blogMapper.selectCount(wrapper);

        Integer totals = size1==0?0:count;
        //计算总页数
        // 如果总数据条数可以整除每一页数据个数, 说明结果正好为总页数
        // 如果总数据条数无法整除每一页数据个数, 说明总页数需要结果 + 1
        Long totalPage =totals%size==0?totals/size: totals/size+ 1;
        //将数据添加到集合
        map.put("current",current);
        map.put("size",size);
        map.put("totals",totals);
        map.put("totalPage",totalPage);
        map.put("blogList",blogList);
        return map;
    }
    /**
     * 缓存热门top5文章
     */
    //@Cacheable(value = "hotBlog",key = "'hotBlog'")
    @Override
    public List<HotBlog> prefindHotBlog() {
        List<HotBlog> blogs = blogMapper.getHotBlog();
        return blogs;
    }
    @Override
    public boolean saveBT(BlogTags blogTags) {
        Blog blog = new Blog();
        blog.setTitle(blogTags.getTitle());
        blog.setDescription(blogTags.getDescription());
        blog.setFirstPicture(blogTags.getFirst_picture());
        blog.setContent(blogTags.getContent());
        blog.setTypeId(blogTags.getType_id());
        blog.setFlag(blogTags.getFlag());
        blog.setPublished(blogTags.getPublished());
        blog.setAppreciation(true);//赞赏
        blog.setCommentabled(true);//评论
        blog.setCreateTime(LocalDateTime.now());
        blog.setRecommend(true);//是否可回复
        blog.setCommentCount(0L);
        blog.setShareStatement(true); //设置状态为已发布
        int result_blog = blogMapper.insert(blog);
        int result_tag = 0, resule_bt = 0;
        List<String> tagsname = blogTags.getTags();
        for (String tagname: tagsname) {
            Tag tag ;
            tag=tagMapper.selectOne(new QueryWrapper<Tag>().eq("name", tagname));
            if(tag==null){
                tag = new Tag();
                tag.setName(tagname);
                result_tag = tagMapper.insert(tag);
            }
            Tags tBlogTags = new Tags();
            tBlogTags.setBlogsId(blog.getId());
            tBlogTags.setTagsId(tag.getId());
            resule_bt = tagsMapper.insert(tBlogTags);
        }
        if (result_blog != 0 && result_tag != 0 && resule_bt !=0){
//            RedisAtomicLong entityIdCounter = new RedisAtomicLong("blogcount", redisTemplate.getConnectionFactory());//文章总数+1
//            entityIdCounter.getAndIncrement();
            return true;
        }
        return false;
    }
    @Override
    public boolean temporarySave(BlogTags blogTags) {
        Blog blog = new Blog();
        blog.setTitle(blogTags.getTitle());
        blog.setDescription(blogTags.getDescription());
        blog.setFirstPicture(blogTags.getFirst_picture());
        blog.setContent(blogTags.getContent());
        //保存文章
        int result_blog = blogMapper.insert(blog);
        if (result_blog != 0){
          return  true;
        }
       return false;
    }

    @Override
    public boolean updateBlog(BlogTags blogTags) {
        Blog blog = blogMapper.selectById(blogTags.getId());
        blog.setTitle(blogTags.getTitle());
        blog.setDescription(blogTags.getDescription());
        blog.setFirstPicture(blogTags.getFirst_picture());
        blog.setContent(blogTags.getContent());
        blog.setTypeId(blogTags.getType_id());
        blog.setFlag(blogTags.getFlag());
        blog.setPublished(blogTags.getPublished());
        blog.setUpdateTime(LocalDateTime.now());

        //更新文章
        int result_blog = blogMapper.updateById(blog);
        int resule_bt = 0;
        //先删除与这篇文章相关的标签和中间表记录
        QueryWrapper<Tags> queryWrapper1 = new QueryWrapper<Tags>();
        queryWrapper1.eq("blogs_id",blog.getId());
        List<Tags> blogTagsList =  tagsMapper.selectList(queryWrapper1);
        for (Tags bt : blogTagsList) {
//            //先删除标签表的数据
            tagMapper.deleteById(bt.getTagsId());
            //再删除博客标签关联表的数据
            QueryWrapper<Tags> queryWrapper = new QueryWrapper<Tags>();
            queryWrapper.eq("tags_id",bt.getTagsId());
            //再删除博客标签关联表的数据
            tagsMapper.delete(queryWrapper);
        }
        //然后再重新添加标签
        List<String> tagsname =  blogTags.getTags();
        for (String tagname: tagsname) {
            Tag tag ;
            tag=tagMapper.selectOne(new QueryWrapper<Tag>().eq("name", tagname));
            if(tag==null){
                tag = new Tag();
                tag.setName(tagname);
                tagMapper.insert(tag);
            }
            Tags tBlogTags = new Tags();
            tBlogTags.setBlogsId(blog.getId());
            tBlogTags.setTagsId(tag.getId());
            tagsMapper.insert(tBlogTags);
            //保存标签
//            Tag tTag = new Tag();
//            tTag.setName(tag);
//            result_tag = tagMapper.insert(tTag);
//            //保存中间表记录
//            Tags tBlogTags = new Tags();
//            tBlogTags.setBlogsId(blog.getId());
//            tBlogTags.setTagsId(tTag.getId());
//            resule_bt = tagsMapper.insert(tBlogTags);
        }
            return true;

    }

    @Override
    public boolean logicDeleteBlog(String id) {
        Blog tBlog = blogMapper.selectById(id);
        if (tBlog != null){
//            RedisAtomicLong entityIdCounter = new RedisAtomicLong("blogcount", redisTemplate.getConnectionFactory());//文章总数-1
//            entityIdCounter.getAndDecrement();
            tBlog.setIsDelete(true);
            tBlog.setUpdateTime(LocalDateTime.now());
            blogMapper.updateById(tBlog);
            return true;
        }else {
            return false;
        }
    }

    @Override
    public boolean deleteBT(String id) {
        Blog tBlog = blogMapper.selectById(id);
        //删除与这篇文章相关的标签和中间表记录
        QueryWrapper<Tags> queryWrapper1 = new QueryWrapper<Tags>();
        queryWrapper1.eq("blogs_id",tBlog.getId());
        List<Tags> blogTagsList =  tagsMapper.selectList(queryWrapper1);
        int r_tag = 0;
        int r_blog_tag = 0;
        for (Tags bt : blogTagsList) {
            //先删除标签表的数据
            r_tag = tagMapper.deleteById(bt.getTagsId());
            //再删除博客标签关联表的数据
            QueryWrapper<Tags> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tags_id",bt.getTagsId());
            //再删除博客标签关联表的数据
            r_blog_tag = tagsMapper.delete(queryWrapper);
        }
        //删除博客文章
        int r_blog = blogMapper.deleteById(id);
        if (r_tag != 0 && r_blog_tag!= 0 && r_blog!= 0){
            return true;
        }else {

            return false;
        }
    }

    /**
     * 恢复博客
     * @param id
     * @return
     */
    @Override
    public boolean recoveryBlog(String id) {
        Blog blog = blogMapper.selectById(id);
        if (blog != null){
//            RedisAtomicLong entityIdCounter = new RedisAtomicLong("blogcount", redisTemplate.getConnectionFactory());//文章总数+1
//            entityIdCounter.getAndIncrement();
            blog.setIsDelete(false);
            blog.setUpdateTime(LocalDateTime.now());
            blogMapper.updateById(blog);
            return true;
        }else {
            return false;
        }
    }

    @Override
    public Blog getByBlogId(String id) {
        Blog blog = blogMapper.getByBlogId(id);
        blog.setViews(blog.getViews() + 1);
//        RedisAtomicLong entityIdCounter = new RedisAtomicLong("views", redisTemplate.getConnectionFactory());//访问总数+1
//        entityIdCounter.getAndIncrement();
        blogMapper.updateById(blog);


        return blog;
    }

    /**
     *
     * @return
     */
    @Override//TODO 接口优化
    public Count countBlog() {
//        Count count = new Count();
//        ValueOperations<String, String> operations = redisTemplate.opsForValue();
//        String views = operations.get("views");
//        String blogcount = operations.get("blogcount");
//        String communitycount = operations.get("communitycount");
//        count.setBlogCount(Integer.valueOf(blogcount));
//        count.setViewCount(Integer.valueOf(views));
//        count.setCommentCount(Long.valueOf(communitycount));
//        count.setMessageCount(Long.valueOf(communitycount));
//        return count;

        Count count = new Count();
        List<CountVo> blogList = baseMapper.findAllBlog();
        int views = 0;
        long comments = 0;
        long messages = 0;
        Blog blog = baseMapper.selectById(-1);
        messages = blog.getCommentCount();
        for (CountVo blog1:blogList) {
            views += blog1.getViews();
            comments += blog1.getCommentCount();
        }
        count.setBlogCount(blogList.size());
        count.setViewCount(views);
        count.setCommentCount(comments);
        count.setMessageCount(messages);

        return count;
    }

    @Override
    public List<FristBlog> vuegetByTitle(String title) {
        List<FristBlog> list = blogMapper.pregetByTitle(title);
        return list;
    }

    @Override
    public void updateByComment(Blog blog) {
        baseMapper.updateById(blog);
    }

    @Override
    public HashMap<String, Object> vuefindByTag(Long current, Long size, Long type_id, Long tags_id) {
        current = current ==null? 0 : current;
        size = size==null? 4 : size;
        HashMap<String,Object> map = new HashMap<>();
        //分页查询出当前页面显示的数据
        List<FristBlog> blogList = blogMapper.prefindByPage((current-1) * size,size,type_id,tags_id);
        //查询数据的总条数
        QueryWrapper<Blog> wrapper = new QueryWrapper<>();
        int size1 = blogList.size();
        wrapper.eq("published",1).eq("share_statement",1);
        if (type_id!=null){
            wrapper.eq("type_id", type_id);
        }
        Integer count = blogMapper.selectCount(wrapper);

        Integer totals = size1==0?0:count;
        //计算总页数
        // 如果总数据条数可以整除每一页数据个数, 说明结果正好为总页数
        // 如果总数据条数无法整除每一页数据个数, 说明总页数需要结果 + 1
        Long totalPage =totals%size==0?totals/size: totals/size+ 1;
        //将数据添加到集合
        map.put("current",current);
        map.put("size",size);
        map.put("totals",totals);
        map.put("totalPage",totalPage);
        map.put("blogList",blogList);

        return map;
    }

}
